<template>
  <el-row :gutter="8">
    <el-col :xs="{span: 24}" :sm="{span: 24}" :md="{span: 24}" :lg="{span: 12}" :xl="{span: 12}" style="padding-right:8px;margin-bottom:30px;">
      <el-table :data="qosData" border :row-class-name="tableRowClassName">
        <el-table-column label="参数" min-width="60">
          <template slot-scope="scope">
            {{ scope.row.key }}
          </template>
        </el-table-column>
        <el-table-column label="值" min-width="60" align="left">
          <template slot-scope="scope">
            {{ scope.row.value | numberFilter(scope.row) }}
          </template>
        </el-table-column>
        <el-table-column label="说明" min-width="200" align="left">
          <template slot-scope="scope">
            {{ scope.row.desc }}
          </template>
        </el-table-column>
      </el-table>
    </el-col>
    <el-col :xs="{span: 24}" :sm="{span: 24}" :md="{span: 24}" :lg="{span: 12}" :xl="{span: 12}" style="padding-right:8px;margin-bottom:30px;">
      <el-row><div id="sendbitrate" :style="{height:height,width:width}" /></el-row>
      <el-row><div id="recvbitrate" :style="{height:height,width:width}" /></el-row>
      <el-row><div id="sendframerate" :style="{height:height,width:width}" /></el-row>
      <el-row><div id="recvframerate" :style="{height:height,width:width}" /></el-row>
    </el-col>
  </el-row>
</template>

<script>
import { mapGetters } from 'vuex'
import { getQos } from '@/api/survery'
import { Message } from 'element-ui'
import resize from '@/mixins/resize'
require('echarts/theme/macarons') // echarts theme
import { toThousandslsFilter } from '@/utils/index.js'

const maxDataCount = 100

export default {
  filters: {
    numberFilter(num, row) {
      if (row.key === '视频接收分辨率' || row.key === '视频发送分辨率') { return num } else { return toThousandslsFilter(num) }
    }
  },
  mixins: [resize],
  props: {
    room: {
      type: String,
      require: true,
      default: ''
    },
    username: {
      type: String,
      require: true,
      default: ''
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '310px'
    }
  },
  data() {
    return {
      timer: null,
      lastQos: {},
      qosData: [
      ],
      recvFrameRateData: [],
      sendFrameRateData: [],
      recvBitRateData: [],
      sendBitRateData: [],
      recvFrameRateChart: null,
      sendFrameRateChart: null,
      recvBitRateChart: null,
      sendBitRateChart: null,
      option: {
        title: {
          text: '动态数据 + 时间坐标轴'
        },
        tooltip: {
          trigger: 'axis',
          formatter: function(params) {
            params = params[0]
            var date = new Date(params.value[0])
            return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' : ' + params.value[1]
          },
          axisPointer: {
            animation: false
          }
        },
        xAxis: {
          type: 'time',
          axisLabel: {
            formatter: function(value, index) {
              return new Date(value).toLocaleTimeString()
            }
          },
          splitLine: {
            show: false
          }
        },
        yAxis: {
          type: 'value',
          boundaryGap: [0, '100%'],
          splitLine: {
            show: false
          }
        },
        series: [{
          name: '模拟数据',
          type: 'line',
          showSymbol: false,
          hoverAnimation: false,
          data: []
        }]
      }
    }
  },
  computed: {
    ...mapGetters(['name', 'roles'])
  },
  mounted() {
  },
  methods: {
    tableRowClassName({ row, rowIndex }) {
      if (row.level === 1) {
        return 'warning-row'
      }
      return ''
    },
    saveChartData(set, data) {
      if (set.length >= maxDataCount) {
        set.shift()
      }
      set.push(data)
    },
    saveQosData(qos) {
      this.qosData = []
      this.qosData.push({ 'key': '音频发送字节', 'value': qos['audio_byte_sent'], 'desc': '服务器上向终端发送的音频字节数', 'level': 0 })
      this.qosData.push({ 'key': '音频发送包数', 'value': qos['audio_packet_sent'], 'desc': '服务器上向终端发送的音频rtp包数', 'level': 0 })
      this.qosData.push({ 'key': '音频接收字节', 'value': qos['audio_byte_recv'], 'desc': '服务器上收到终端发送的音频字节数', 'level': 0 })
      this.qosData.push({ 'key': '音频接收包数', 'value': qos['audio_packet_recv'], 'desc': '服务器上收到终端发送的音频rtp包数', 'level': 0 })
      this.qosData.push({ 'key': '音频接收丢包数', 'value': qos['audio_packet_lost_recv'], 'desc': '服务器上接收音频丢包数', 'level': qos['audio_packet_lost_recv'] - this.lastQos['audio_packet_lost_recv'] > 0 ? 1 : 0 })

      this.qosData.push({ 'key': '视频发送字节', 'value': qos['video_byte_sent'], 'desc': '服务器上向终端发送的视频字节数', 'level': 0 })
      this.qosData.push({ 'key': '视频发送包数', 'value': qos['video_packet_sent'], 'desc': '服务器上向终端发送的视频rtp包数', 'level': 0 })
      this.qosData.push({ 'key': '视频发送FIR数', 'value': qos['fir_count_sent'], 'desc': '服务器上向终端发送的首帧请求数', 'level': qos['fir_count_sent'] - this.lastQos['fir_count_sent'] > 0 ? 1 : 0 })
      this.qosData.push({ 'key': '视频发送NACK数', 'value': qos['nack_count_sent'], 'desc': '服务器上向终端发送的丢包重传请求数，通常在网络质量不好的情况下，服务器将发送此消息通知终端重传', 'level': qos['nack_count_sent'] - this.lastQos['nack_count_sent'] > 0 ? 1 : 0 })
      this.qosData.push({ 'key': '视频发送PLI数', 'value': qos['pli_count_sent'], 'desc': '服务器上向终端发送的IDR帧请求数，通常在有新终端加入会议后，服务器会通过PLI请求向画面源终端请求I帧', 'level': qos['pli_count_sent'] - this.lastQos['pli_count_sent'] > 0 ? 1 : 0 })

      this.qosData.push({ 'key': '视频接收字节', 'value': qos['video_byte_recv'], 'desc': '服务器上收到终端发送的视频字节数', 'level': 0 })
      this.qosData.push({ 'key': '视频接收包数', 'value': qos['video_packet_recv'], 'desc': '服务器上收到终端发送的视频rtp包数', 'level': 0 })
      this.qosData.push({ 'key': '视频接收丢包数', 'value': qos['video_packet_lost_recv'], 'desc': '服务器上接收视频丢包数', 'level': qos['video_packet_lost_recv'] - this.lastQos['video_packet_lost_recv'] > 0 ? 1 : 0 })
      this.qosData.push({ 'key': '视频接收FIR数', 'value': qos['fir_count_recv'], 'desc': '服务器上接收终端发送的首帧请求数，通常终端在刚加入会议时发送FIR请求首帧', 'level': qos['fir_count_recv'] - this.lastQos['fir_count_recv'] > 0 ? 1 : 0 })
      this.qosData.push({ 'key': '视频接收NACK数', 'value': qos['nack_count_recv'], 'desc': '服务器上接收终端发送的丢包重传请求数，通常在网络质量不好的情况下，终端将发送此消息通知服务端重传', 'level': qos['nack_count_recv'] - this.lastQos['nack_count_recv'] > 0 ? 1 : 0 })
      this.qosData.push({ 'key': '视频接收PLI数', 'value': qos['pli_count_recv'], 'desc': '服务器上接收终端发送的IDR帧请求数，通常终端建立解码器时需要发送PLI请求I帧', 'level': qos['pli_count_recv'] - this.lastQos['pli_count_recv'] > 0 ? 1 : 0 })

      this.qosData.push({ 'key': '视频发送帧数', 'value': qos['send_video_frame'], 'desc': '服务器上向终端发送的视频帧数', 'level': 0 })

      if (qos['send_video_width']) {
        this.qosData.push({ 'key': '视频发送分辨率', 'value': qos['send_video_width'] + '*' + qos['send_video_height'], 'desc': '服务器上向终端发送的视频分辨率', 'level': 0 })
      } else {
        this.qosData.push({ 'key': '视频发送分辨率', 'value': '无效', 'desc': '服务器上向终端发送的视频分辨率', 'level': 0 })
      }

      this.qosData.push({ 'key': '视频接收帧数', 'value': qos['video_frame_decoded'], 'desc': '服务器上成功解码出的帧数', 'level': 0 })
      if (qos['recv_video_width']) {
        this.qosData.push({ 'key': '视频接收分辨率', 'value': qos['recv_video_width'] + '*' + qos['recv_video_height'], 'desc': '服务器接收终端发来的视频分辨率', 'level': 0 })
      } else {
        this.qosData.push({ 'key': '视频接收分辨率', 'value': '无效', 'desc': '服务器接收终端发来的视频分辨率，当会议时SFU会议时，由于服务器不解码，数值无效', 'level': 0 })
      }
      var now = Date.parse(new Date())
      var sendbr = 0
      var recvbr = 0
      var sendfps = 0
      var recvfps = 0

      if (this.lastQos['last_time']) {
        // 计算比特率
        if (now - this.lastQos['last_time'] !== 0) {
          sendbr = 8 * (qos['video_byte_sent'] - this.lastQos['last_video_byte_sent']) / (now - this.lastQos['last_time']) / 1024 * 1000
          recvbr = 8 * (qos['video_byte_recv'] - this.lastQos['last_video_byte_recv']) / (now - this.lastQos['last_time']) / 1024 * 1000
        }

        // 计算帧率
        if (now - this.lastQos['last_time'] !== 0) {
          sendfps = (qos['send_video_frame'] - this.lastQos['last_send_video_frame']) / (now - this.lastQos['last_time']) * 1000
          recvfps = (qos['video_frame_decoded'] - this.lastQos['last_video_frame_decoded']) / (now - this.lastQos['last_time']) * 1000
        }

        this.qosData.push({ 'key': '视频发送码率', 'value': sendbr, 'desc': '服务器发送码率，单位：kbps', 'level': 0 })
        this.qosData.push({ 'key': '视频接收码率', 'value': recvbr, 'desc': '服务器接收码率，单位：kbps', 'level': 0 })
        this.qosData.push({ 'key': '视频发送帧率', 'value': sendfps, 'desc': '服务器发送帧率', 'level': 0 })
        this.qosData.push({ 'key': '视频接收帧率', 'value': recvfps, 'desc': '服务器接收帧率', 'level': 0 })

        this.saveChartData(this.sendBitRateData, { 'name': now, 'value': [now, sendbr] })
        this.saveChartData(this.recvBitRateData, { 'name': now, 'value': [now, recvbr] })
        this.saveChartData(this.sendFrameRateData, { 'name': now, 'value': [now, sendfps] })
        this.saveChartData(this.recvFrameRateData, { 'name': now, 'value': [now, recvfps] })

        this.recvFrameRateChart.setOption(
          { series: [{
            data: this.recvFrameRateData
          }]
          })
        this.sendFrameRateChart.setOption(
          { series: [{
            data: this.sendFrameRateData
          }]
          })
        this.recvBitRateChart.setOption(
          { series: [{
            data: this.recvBitRateData
          }]
          })
        this.sendBitRateChart.setOption(
          { series: [{
            data: this.sendBitRateData
          }]
          })
      }

      this.lastQos['last_video_byte_sent'] = qos['video_byte_sent']
      this.lastQos['last_video_byte_recv'] = qos['video_byte_recv']
      this.lastQos['last_send_video_frame'] = qos['send_video_frame']
      this.lastQos['last_video_frame_decoded'] = qos['video_frame_decoded']

      this.lastQos['audio_packet_lost_recv'] = qos['audio_packet_lost_recv']
      this.lastQos['video_packet_lost_recv'] = qos['video_packet_lost_recv']
      this.lastQos['fir_count_recv'] = qos['fir_count_recv']
      this.lastQos['nack_count_recv'] = qos['nack_count_recv']
      this.lastQos['pli_count_recv'] = qos['pli_count_recv']
      this.lastQos['fir_count_sent'] = qos['fir_count_sent']
      this.lastQos['nack_count_sent'] = qos['nack_count_sent']
      this.lastQos['pli_count_sent'] = qos['pli_count_sent']
      this.lastQos['last_time'] = now
    },
    getQosDetail(room, username) {
      const _this = this
      getQos(room, username)
        .then((response) => {
          if (response.error_code === 200) {
            const qos = JSON.parse(response.data.qos)
            _this.saveQosData(qos)
            _this.initChart()
          }
        })
        .catch((error) => {
          Message.error(error)
        })
      this.timer = setInterval(() => {
        getQos(room, username)
          .then((response) => {
            if (response.error_code === 200) {
              const qos = JSON.parse(response.data.qos)
              _this.saveQosData(qos)
            }
          })
          .catch((error) => {
            Message.error(error)
          })
      }, 1000)

      // 通过$once来监听定时器，在beforeDestroy钩子可以被清除。
      this.$once('hook:beforeDestroy', () => {
        console.log('清除定时器')
        clearInterval(this.timer)
      })
    },
    clearTimer() {
      console.log('外部指定清除定时器')
      clearInterval(this.timer)
    },
    initChart() {
      this.recvBitRateChart = this.$echarts.init(
        document.getElementById('sendbitrate'),
        'macarons'
      )
      this.sendBitRateChart = this.$echarts.init(
        document.getElementById('recvbitrate'),
        'macarons'
      )
      this.recvFrameRateChart = this.$echarts.init(
        document.getElementById('sendframerate'),
        'macarons'
      )
      this.sendFrameRateChart = this.$echarts.init(
        document.getElementById('recvframerate'),
        'macarons'
      )

      this.option.title.text = '接收码率'
      this.option.series.name = 'recvBitRateChart'
      this.recvBitRateChart.setOption(this.option)

      this.option.title.text = '发送码率'
      this.option.series.name = 'sendBitRateChart'
      this.sendBitRateChart.setOption(this.option)

      this.option.title.text = '接收帧率'
      this.option.series.name = 'recvFrameRateChart'
      this.recvFrameRateChart.setOption(this.option)

      this.option.title.text = '发送帧率'
      this.option.series.name = 'sendFrameRateChart'
      this.sendFrameRateChart.setOption(this.option)

      const now = Date.parse(new Date())
      for (var i = 0; i < maxDataCount; i++) {
        const previous = now - (1000 * (maxDataCount - i - 1))
        this.saveChartData(this.sendBitRateData, { 'name': previous, 'value': [previous, 0] })
        this.saveChartData(this.recvBitRateData, { 'name': previous, 'value': [previous, 0] })
        this.saveChartData(this.sendFrameRateData, { 'name': previous, 'value': [previous, 0] })
        this.saveChartData(this.recvFrameRateData, { 'name': previous, 'value': [previous, 0] })
      }

      this.recvFrameRateChart.setOption(
        { series: [{
          data: this.recvFrameRateData
        }]
        })
      this.sendFrameRateChart.setOption(
        { series: [{
          data: this.sendFrameRateData
        }]
        })
      this.recvBitRateChart.setOption(
        { series: [{
          data: this.recvBitRateData
        }]
        })
      this.sendBitRateChart.setOption(
        { series: [{
          data: this.sendBitRateData
        }]
        })
    }
  }
}
</script>

<style lang="scss" >
.el-table .warning-row {
      background: oldlace;
    }
.box-card-component {
  .el-card__header {
    padding: 0px !important;
  }
  .el-card__body {
    padding: 0px !important;
  }
}
</style>
<style lang="scss" scoped>

.box-card-component {
  .box-card-header {
    position: relative;
    height: 220px;
    img {
      width: 100%;
      height: 100%;
      transition: all 0.2s linear;
      &:hover {
        transform: scale(1.1, 1.1);
        filter: contrast(130%);
      }
    }
  }
  .card-panel-text {
    line-height: 18px;
    color: rgba(0, 0, 0, 0.55);
    font-size: medium;
    font-weight: bold;
    margin-top: 14px;
    margin-left: 14px;
  }
  .progress-item {
    margin-bottom: 10px;
    font-size: 14px;
  }
  .el-header,
  .el-footer {
    background-color: #b3c0d1;
    color: #333;
    text-align: center;
    line-height: 60px;
  }

  .el-aside {
    background-color: #d3dce6;
    color: #333;
    div {
      text-align: center;
      vertical-align: middle;
      display: table-cell;
      margin: auto;
    }
  }

  .el-main {
    background-color: #e9eef3;
    color: #333;
    text-align: center;
    vertical-align: middle;
    line-height: 40px;
  }

  body > .el-container {
    margin-bottom: 40px;
  }

  .el-container:nth-child(5) .el-aside,
  .el-container:nth-child(6) .el-aside {
    line-height: 260px;
  }

  .el-container:nth-child(7) .el-aside {
    line-height: 320px;
  }
  .el-row {
    margin-bottom: 20px;
    &:last-child {
      margin-bottom: 0;
    }
  }
  .el-col {
    border-radius: 4px;
  }
  .bg-purple-dark {
    background: #99a9bf;
  }
  .bg-purple {
    background: #d3dce6;
  }
  .bg-purple-light {
    background: #e5e9f2;
  }
  .grid-content {
    border-radius: 4px;
    min-height: 36px;
    text-align: center;
    vertical-align: middle;
  }
  .row-bg {
    padding: 10px 0;
    background-color: #f9fafc;
  }
  @media only screen and (max-width: 1510px) {
    .mallki-text {
      display: none;
    }
  }
}
</style>
